// 
// Author: damphat@gmail.com
//

#include "vn/TimeSpan.h"
#include <assert.h>

#define MillisPerSecond		1000LL
#define MillisPerMinute		60000LL
#define MillisPerHour		3600000LL
#define MillisPerDay		86400000LL

TimeSpan::TimeSpan( Int64 miliseconds /*= 0*/ ) {
	data = miliseconds;
}

TimeSpan::TimeSpan( int hours, int minutes, int seconds ) {
	data 
		= hours   * MillisPerHour
		+ minutes * MillisPerMinute
		+ seconds * MillisPerSecond;
}

TimeSpan::TimeSpan( int days, int hours, int minutes, int seconds, int milliseconds /*= 0*/ ) {
	data 
		= days    * MillisPerDay
		+ hours   * MillisPerHour
		+ minutes * MillisPerMinute
		+ seconds * MillisPerSecond
		+ milliseconds;
}

TimeSpan::TimeSpan( double totalLength, TimeUnit unit ) {
	switch (unit) {
	case Days:
		data = Int64(totalLength * MillisPerDay);
		break;
	case Hours:
		data = Int64(totalLength * MillisPerHour);
		break;
	case Minutes:
		data = Int64(totalLength * MillisPerMinute);
		break;
	case Seconds:
		data = Int64(totalLength * MillisPerSecond);
		break;
	case Miliseconds:
		data = Int64(totalLength);
		break;
	default:
		assert(false);	// Unknown unit
	}
}

int TimeSpan::GetDays() const {
	return (int) (data / MillisPerDay);
}

int TimeSpan::GetHours() const {
	return (int) ((data / MillisPerHour) % 24LL);
}

int TimeSpan::GetMinutes() const {
	return (int) ((data / MillisPerMinute) % 60LL);
}

int TimeSpan::GetSeconds() const {
	return (int) ((data / MillisPerSecond) % 60LL);
}

int TimeSpan::GetMilliseconds() const {
	return (int) (data % MillisPerSecond);
}

double TimeSpan::GetTotalDays() const {
	return data / (double)MillisPerDay;
}

double TimeSpan::GetTotalHours() const {
	return data / (double)MillisPerHour;
}

double TimeSpan::GetTotalMinutes() const {
	return data / (double)MillisPerMinute;
}

double TimeSpan::GetTotalSeconds() const {
	return data / (double)MillisPerSecond;
}

double TimeSpan::GetTotalMilliseconds() const {
	return (double)data;
}

// Operators
TimeSpan operator -(TimeSpan t) {
	return -t.data;
}

TimeSpan operator -(TimeSpan t1, TimeSpan t2) {
	return t1.data - t2.data;
}

TimeSpan operator +(TimeSpan t1, TimeSpan t2) {
	return t1.data + t2.data;
}

bool operator ==(TimeSpan t1, TimeSpan t2) {
	return t1.data == t2.data;
}

bool operator !=(TimeSpan t1, TimeSpan t2) {
	return t1.data != t2.data;
}

bool operator <(TimeSpan t1, TimeSpan t2) {
	return t1.data < t2.data;
}

bool operator <=(TimeSpan t1, TimeSpan t2) {
	return t1.data <= t2.data;
}

bool operator >(TimeSpan t1, TimeSpan t2) {
	return t1.data > t2.data;
}

bool operator >=(TimeSpan t1, TimeSpan t2) {
	return t1.data >= t2.data;
}
